﻿using System;
using System.Collections.Generic;
using System.Linq;
using ch.froorider.NGoogleCalendar.tools;
using Google.GData.Calendar;
using log4net;
using CH.Froorider.Codeheap.Configuration;

namespace ch.froorider.NGoogleCalendar.googleService
{
	/// <summary>
	/// Wrapper class for the functionality. This object represents a google calendar.
	/// All data is stored here. The data is then synchronized with the account. All
	/// things you can do with a calendar are accessible through this object.
	/// </summary>
	public class Calendar
	{
		private GoogleAccount account;
		private readonly string allCalendarsUrl ;
		private readonly string baseCalendarFeed ;
		private readonly string privateFeedExtension ;

	    readonly List<String> calendarList = new List<String>();
	    readonly List<EventItem> taskList = new List<EventItem>();

		//Not used at the moment
		private static ILog logger = LogManager.GetLogger(typeof(Calendar));

		/// <summary>
		/// Default constructor. Use this if you do not have the desired information
		/// about the account yet.
		/// </summary>
		public Calendar()
		{
			LibraryConfigurationManager.Load("NGoogleCalendar.dll.config");
			allCalendarsUrl = LibraryConfigurationManager.LoadedKeys["AllCalendarsFeedUrl"];
			baseCalendarFeed = LibraryConfigurationManager.LoadedKeys["BaseCalendarFeed"];
			privateFeedExtension = LibraryConfigurationManager.LoadedKeys["PrivateFeed"];
		}

		/// <summary>
		/// Constructor. Inits the calendar with the basic information.
		/// </summary>
		/// <param name="userName"></param>
		/// <param name="pass"></param>
		public Calendar(string userName, string pass): this()
		{
			try
			{
				LibraryConfigurationManager.Load("NGoogleCalendar.dll.config");
			}
			catch(ArgumentException ae)
			{
				logger.Error(ae);
				throw new NGoogleCalendarException(ae.Message);
			}

			try
			{
				account = new GoogleAccount(userName, pass);
			}
			catch (NGoogleCalendarException ngcae)
			{
				logger.Error("Couldn't create account. Cause: " + ngcae.Message);
				throw;
			}
		}

		/// <summary>
		/// Log into an existing account.
		/// </summary>
		/// <param name="userName">The username (email) of your account</param>
		/// <param name="pass"></param>
		/// <exception cref="System.ApplicationException">Is thrown, if the username or password is wrong.</exception>
		public void LogOn(string userName, string pass)
		{
			if (account == null)
			{
				try
				{
					account = new GoogleAccount(userName, pass);
				}
				catch (NGoogleCalendarException ngcae)
				{
					logger.Error("Couldn't create account. Cause: " + ngcae.Message);
					throw;
				}
			}
			else
			{
				logger.Info("Log out first.");
			}
		}

        /// <summary>
        /// Gives you the list of calendars of this account.
        /// </summary>
        /// <returns>List containing the names of the calendars</returns>
        public List<String> GetCalendarList()
        {
            CalendarQuery query = new CalendarQuery();

            query.Uri = new Uri(allCalendarsUrl);
            CalendarFeed resultFeed = account.Service.Query(query);
            
            foreach (CalendarEntry entry in resultFeed.Entries)
            {
                calendarList.Add(entry.Title.Text);
				logger.Debug("Calendar name found: " + entry.Title.Text);
            }

            return calendarList;
        }

		/// <summary>
		/// Gets the list of tasks defined in the private calendar feed
		/// </summary>
		/// <returns>A list of strings containig the event entries</returns>
		public List<String> GetTaskList()
		{
			EventQuery query = new EventQuery();
			Uri calendarUri = new Uri( baseCalendarFeed + account.AccountName + privateFeedExtension);

			query.Uri = calendarUri;
			EventFeed tasks = account.Service.Query(query);
			
			foreach (EventEntry entry in tasks.Entries)
			{
				taskList.Add(new EventItem(entry));
				logger.Debug("Task entry found: " + entry.Title.Text);
			}
			
			List<String> returnValue = new List<string>();
			foreach (EventItem currentItem in taskList.ToList())
			{
				returnValue.Add(currentItem.Title);
			}
			return returnValue;
		}
	}
}
